package pw.goyd.game.api;

import pw.goyd.game.constant.setting.GameSetting;
import pw.goyd.game.constant.setting.StateCode;
import pw.goyd.game.manager.RoomManager;
import pw.goyd.game.model.Room;
import pw.goyd.game.model.Seat;
import pw.goyd.game.server.Log;
import pw.goyd.game.server.Server;
import pw.goyd.subscribe.PlayerCustomer;

import java.util.*;

/**
 * 周期检查任务
 *
 * @author StanWind
 */
public class RunningTask extends TimerTask implements GameSetting, StateCode, Thread.UncaughtExceptionHandler {
    /**
     * 线程异常补获
     *
     * @param t 线程
     * @param e 错误信息
     */
    @Override
    public void uncaughtException(Thread t, Throwable e) {
        Log.getLogger().error("定时任务线程异常...", e);
    }

    @Override
    public void run() {
        try {
            Server.addServerTime(); //  计时
            // 处理所有房间的准备
            Iterator<Room> it = RoomManager.reayRoom.iterator();        //迭代遍历
            while (it.hasNext()) {
                final Room r = it.next();
                if (r.getReadyTime() != -1
                        && (Server.getServerTime() - r.getReadyTime()) >= READY_TIME) { //  倒计时是否到
                    r.setReadyTime(Server.getServerTime());             // 继续持续时间
                    switch (r.getStep()) {                              //  步骤选择
                        case STEP_READY:                                //  步骤 准备
                            r.setStep(2);
                            r.setReadyTime(Server.getServerTime() + 5); // 继续持续时间
                            Log.getLogger().info(
                                    "发牌----> room［" + r.getRoomID() + "]");
                            // 发牌 开始游戏线程
                            new Thread(() -> {
                                // 初始房间
                                r.setGame(true);
                                r.initCards();
                                //正在玩的玩家lsit
                                List<PlayerCustomer> playingList = new ArrayList<>();
                                // 拿到所有座位
                                List<Seat> seats = r.getSeats();
                                for (Seat s : seats) {
                                    PlayerCustomer p = s.getPlayer();
                                    if (p != null) {
                                        // 未准备

                                        p.setReady(false);
                                        p.setBet(-1);
                                        p.setDeclarer(-1);
                                        //初始化手牌
                                        p.setCards(new ArrayList<>());
                                        // 发牌四张
                                        p.getCards().add(r.getRandCard());
                                        p.getCards().add(r.getRandCard());
                                        p.getCards().add(r.getRandCard());
                                        p.getCards().add(r.getRandCard());
                                        p.sendCards();
                                        playingList.add(p);
                                    }
                                }
                                r.setIsPlayingPlayer(playingList);  // 设定房间正在玩的玩家
                                r.pubTimeDown();                    // 发送倒计时
                                r.deductTableFee();
                            }).start();

                            break;
                        case STEP_DECLARER:
                            r.setStep(3);
                            // 给十秒
                            r.setReadyTime(Server.getServerTime() + 5);
                            Log.getLogger().info(
                                    "抢庄----> room［" + r.getRoomID() + "]");
                            // 发牌 开始游戏线程
                            new Thread(() -> {
                                // 随机队列
                                List<PlayerCustomer> randList = new ArrayList<>();
                                List<PlayerCustomer> declaList = r.getIsPlayingPlayer();
                                int maxDecla = 0;
                                for (PlayerCustomer p : r.getIsPlayingPlayer()) {
                                    //刚刚发过牌 才是正在玩的玩家
                                    if (p != null) {
                                        int temp = p.getDeclarer();
                                        if (temp > 0) {
                                            if (temp == maxDecla) {
                                                // 加入随机队列最高倍数
                                                randList.add(p);
                                            } else if (temp > maxDecla) {
                                                // 更新最高倍数 和随机队列
                                                maxDecla = temp;
                                                randList.clear();
                                                randList.add(p);
                                            } else {
                                                // 无效提交倍数
                                                Log.getLogger().info("危险---->玩家[" + p.getNickname() + "]提交倍数无效");
                                            }
                                        } else if (temp == -1) {
                                            p.setDeclarer(0);
                                            p.sendDeclarer();
                                        }
                                    }
                                }
                                // 开始随机出庄
                                Random rand = new Random();
                                PlayerCustomer declarer;
                                if (maxDecla != 0) {

                                    declarer = randList.get(rand.nextInt(randList
                                            .size()));
                                } else {
                                    Log.getLogger().debug("无人抢庄");
                                    declarer = declaList.get(rand.nextInt(declaList
                                            .size()));
                                }
                                Log.getLogger().info("庄家---->" + declarer.getNickname());
                                declarer.setDeclarer(1);        //  设置最低分数
                                r.setDeclarerPlayer(declarer);
                                r.pubDeclarer();                //  推送庄家
                                r.pubTimeDown();                //  发送倒计时
                            }).start();
                            break;
                        case STEP_BET:
                            r.setReadyTime(Server.getServerTime() + 4);
                            r.setStep(4);
                            Log.getLogger().info(
                                    "下注----> room［" + r.getRoomID() + "]");
                            // 发牌 开始游戏线程
                            new Thread(() -> {
                                // 遍历正在玩的玩家
                                for (PlayerCustomer p : r.getIsPlayingPlayer()) {
                                    if (p.getBet() == -1) {
                                        p.setBet(5);    // 没下注 默认5
                                        p.sendBet();    // 推送到房间
                                    }
                                    // 随机最后一张牌
                                    p.getCards().add(r.getRandCard());
                                    p.sendLastCard();
                                    p.calcCards();  // 算牌
                                    Log.getLogger().info("[" + p.getNickname() + "]" + p.getCards().toString());
                                }
                                r.calcGolds();      // 结算金钱
                                r.pubTimeDown();    // 发送倒计时
                            }).start();
                            break;
                        case STEP_COMPLETE:
                            new Thread(() -> {
                                while (!r.isCalcGolds()) {
                                    // 未结算完毕
                                }
                                Log.getLogger().debug(
                                        "结算----> room [" + r.getRoomID() + "]");
                                r.setCalcGolds(false);      //  结算初始化
                                r.setStep(1);               //  步骤初始化
                                r.setReadyTime(-1);         //  task时间初始化
                                r.pubShowCards();           //  推送所有牌
                                r.clearCards();             //  清除玩家手牌
                                r.pubGolds();               //  推送金币
                                r.setGame(false);           //  游戏结束
                                r.handleTask();             //  结束任务执行
                                r.setIsPlayingPlayer(new ArrayList<>()); //  清除正在玩的玩家
                                r.setDeclarerPlayer(null);  //  清空庄家
                                //r.setIsPlayingPlayer(null); //  清空正在游戏玩家
                            }).start();

                            break;
                        default:
                            break;
                    }

                }
            }
        } catch (Exception e) {
            Log.getLogger().error("定时任务线程异常", e);
        }
    }


}
